package com.test.www.util;

import java.util.*;

/**
 * <p>自建的动态数组数据结构</p>
 * @author Bosen
 * 2020/12/18 20:55
 */
public class IArrayList<T> implements Iterable<T> {
    //初始容量
    private static final int DEFAULT_CAPACITY = 10;
    //存储元素的数组
    private T[] array;
    //有效元素数量
    private int size;

    public IArrayList() {
        doClear();
    }

    private void doClear() {
        size = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void add(T val) {
        add(size, val);
    }

    //添加元素到末尾，若空间不够则扩容
    public void add(int idx, T val) {
        if (idx < 0 || idx > size) {
            throw new IndexOutOfBoundsException();
        }
        if (array.length == size) {
            ensureCapacity(size/2 + size);
        }
        for (int i = size - 1; i >= idx; i++) {
            array[i + 1] = array[i];
        }

        array[idx] = val;
        size++;
    }

    //删除元素
    public T remove(int idx) {
        if (idx < 0 || idx >= size) {
            throw new IndexOutOfBoundsException();
        }

        T removeItem = array[idx];
        for (int i = idx + 1; i < size; i++) {
            array[i - 1] = array[i];
        }

        size--;
        return removeItem;
    }

    //设置元素
    public T set(int idx, T newVal) {
        if (idx < 0 || idx >= size) {
            throw new IndexOutOfBoundsException();
        }
        T oldVal = array[idx];
        array[idx] = newVal;
        return oldVal;
    }

    //获取元素
    public T get(int idx) {
        if (idx < 0 || idx >= size) {
            throw new IndexOutOfBoundsException();
        }

        return array[idx];
    }

    //扩容
    private void ensureCapacity(int newCapacity) {
        if (newCapacity < size) {
            return;
        }

        @SuppressWarnings("unchecked")
        T[] newItems = (T[]) new Object[newCapacity];
        for (int i = 0; i < size; i++) {
            newItems[i] = array[i];
        }

        array = newItems;

    }

    //获取迭代器
    @Override
    public Iterator<T> iterator() {
        return new MyArrayListIterator();
    }

    //迭代器内部类
    private class MyArrayListIterator implements Iterator<T> {
        //当前迭代元素下标
        private int current = 0;
        private boolean okToMove = false;

        @Override
        public boolean hasNext() {
            return current < size;
        }

        //获取下一个元素
        @Override
        public T next() {
            //没有元素抛出异常
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            //标记可以删除前一个元素
            okToMove = true;
            //返回当前元素并且指针向前推进一位
            return array[current++];
        }

        public void remove() {
            if (!okToMove) {
                throw new IllegalStateException();
            }

            IArrayList.this.remove(--current);
            //这里由于remove修改了modCount值因此需要重新赋值，否则后面的操作会抛异常
            okToMove = false;
        }

    }
}
